1、中断硬件框架
	中断硬件框架主要包括3个部分，分别是中断源、中断控制器、CPU
	中断源：产生中断信号给中断控制器
	中断控制器：对中断进行配置（如使能禁止、优先级、分发等），并将中断信号给CPU（也可能是给上一级中断控制器）
	CPU：执行中断处理程序
2、中断产生和处理流程
	如下是中断产生和处理流程，其中a~c由硬件完成，d~f由软件完成
	a）中断源产生中断信号
	b）中断控制器中断CPU
	c）CPU从中断向量表找到中断服务程序
	d）中断服务程序读取中断控制器寄存器得到中断源
	e）中断服务程序读取中断源外设得到中断原因
	f）处理中断事件
3、 GIC结构和功能
	通用中断控制器（GIC）主要包括两个部分：分发器（GICD）、CPU接口（GICC）
	分发器（GICD）：负责使能或禁止中断、配置中断其优先级、将中断分发到CPU接口，在分发器中除了对共享中断（32~
1019号中断）进行配置和分发外，它还能对每个CPU接口对应的软中断（0~15号中断）和私有中断（16~31号中断）进行配置
	CPU接口（GICC）：负责按优先级屏蔽中断、向CPU产生IRQ或FIQ中断CPU（CPU被中断后会进入IRQ或FIQ中断函数）
4、中断类型
	通用中断控制器（GIC）有3种类型的中断，分别是软中断（SGI）、私有中断（PPI）、共享中断（SPI），
	软中断（SGI）：中断号0~15，通过软件写寄存器的方式进行触发，每个CPU接口都有自己的软中断（SGI），虽然它们编
号相同，但物理上却不是同一个
	私有中断（PPI）：中断号16~31，一般用于连接CPU核心的私有外设，每个CPU接口都有自己的私有中断（PPI），虽然它
们编号相同，但物理上却不是同一个
	共享中断（SPI）：中断号32~1019，一般用于连接CPU上的公共外设，这些中断为所有CPU接口共享
5、中断状态
	一个中断有4种状态，分别是非活动状态、挂起状态、活动状态、活动和挂起状态
	非活动状态：这意味着该中断未触发
	挂起状态：这意味着中断源已被触发，但正在等待CPU核处理
	活动状态：已被内核接收并正在处理的中断
	活动和挂起状态：CPU正在为中断服务，而GIC又收到来自同一源的中断
7、中断向量表
	如下是ARM Linux的中断向量表：
	.section .vectors, "ax", %progbits
	.L__vectors_start:
	W(b)	vector_rst
	W(b)	vector_und
	W(ldr)	pc, .L__vectors_start + 0x1000
	W(b)	vector_pabt
	W(b)	vector_dabt
	W(b)	vector_addrexcptn
	W(b)	vector_irq
	W(b)	vector_fiq
	Linux初始化过程中会将异常向量表搬移到特定的虚拟地址（0xffff0000），当中断发生时CPU会跳转到异常向量表中执
行相应的程序（一般是一条跳转指令）
8、ARM Linux的中断调用流程
	当GIC产生IRQ中断时CPU会跳转到中断向量表执行”W(b) vector_irq“，然后跳转到vector_irq汇编函数中执行，根据中
断前CPU模式去执行__irq_usr或__irq_svc汇编函数，然后调用irq_handler汇编函数，再通过handle_arch_irq全局变量调
用GIC提供的中断处理函数，其流程如下：
	W(b) vector_irq
		vector_irq
			根据CPU模式执行__irq_usr或__irq_svc
				irq_handler
					通过全局变量handle_arch_irq调用gic_handle_irq
						//读取硬件中断号
						irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
						irqnr = irqstat & GICC_IAR_INT_ID_MASK;
						//处理硬件中断
						handle_domain_irq(gic->domain, irqnr, regs);
							__handle_domain_irq(domain, hwirq, true, regs);
								//根据硬件中断号找到软件中断号
								generic_handle_irq(irq);
									//根据软件中断号找到irq_desc
									generic_handle_irq_desc(desc);
										//在GIC irq_domain提供的alloc函数中将handle_irq设置为handle_fasteoi_irq
										//或handle_percpu_devid_irq
										desc->handle_irq(desc);
9、GIC初始化函数调用流程
	在Linux中通过宏IRQCHIP_DECLARE将GIC初始化函数及对应的设备树匹配信息放到__irqchip_of_table数据段中，如下是
A7的GIC初始化函数与设备树匹配信息的定义：
	IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
	展开后如下：
	static const struct of_device_id __of_table_cortex_a7_gic		\
	__used __section(__irqchip_of_table)			\
	 = { .compatible = "arm,cortex-a7-gic",				\
		 .data = gic_of_init  }
	在系统初始化的时候通过中断控制器compatible属性与__irqchip_of_table数据段中每一项的compatible进行匹配，若
匹配成功则调用相应的初始化函数，其流程如下：
	start_kernel (init\main.c)
    init_IRQ (arch\arm\kernel\irq.c)
    	irqchip_init (drivers\irqchip\irqchip.c)
    		of_irq_init(__irqchip_of_table) (drivers\of\irq.c)
				//使用__irqchip_of_table与中断控制器设备树节点进行匹配，匹配成功得到对应中断控制器初始化函数
				desc->irq_init_cb = match->data;
				//执行中断控制器初始化函数，对于cortex a7应该是gic_of_init
                ret = desc->irq_init_cb(desc->dev, desc->interrupt_parent);
9、GIC初始化流程
	如下是Linux中对GIC控制器的初始化流程：
	gic_of_init
		//将控制寄存器的物理地址映射到虚拟地址
		gic_of_setup
		__gic_init_bases
			//设置全局变量handle_arch_irq
			set_handle_irq
			//初始化gic chip，设置irq_chip成员
			gic_init_chip
			gic_init_bases
				//创建GIC的中断域
				irq_domain_create_linear
				//硬件初始化
				gic_dist_init
				gic_cpu_init
				gic_pm_init

